package m2st.doxia.macro;

import java.io.IOException;
import java.net.URL;

import org.apache.maven.doxia.macro.Macro;
import org.apache.maven.doxia.macro.MacroExecutionException;
import org.apache.maven.doxia.macro.MacroRequest;
import org.apache.maven.doxia.sink.Sink;

/**
 * {@link Macro} for inserting code snippets into the output document.
 * 
 * <p>
 * 
 * You can specify the source file location using the <tt>file</tt>
 * or <tt>url</tt> parameter (<tt>url</tt> parameter always takes
 * precedence over the <tt>file</tt> if specified).
 * 
 * <p>
 * 
 * Optional macro parameters include:
 * 
 * <ul>
 *  <li><tt>id</tt> - snippet identifier (can be omitted to include
 *      the entire source file contents)
 *  <li><tt>encoding</tt> - source file encoding (can be omitted to
 *      use <tt>UTF-8</tt> by default)
 *  <li><tt>brush</tt> - brush alias to use for syntax highlighting
 *  <li><tt>brush-autodetect</tt> - brush alias autodetection flag
 *      (if specified, brush alias will be automatically set according
 *      to the source file extension, note that this overrides the
 *      <tt>brush</tt> parameter value)
 *  <li><tt>sh-params</tt> - additional syntax highlighter parameters
 *      (applicable only in case the brush alias has been set)
 * </ul>
 * 
 * <p>
 * 
 * Snippet syntax highlighting can be achieved in conjunction with
 * the <tt>stylus-ext-skin</tt> project which is essentially a custom
 * Maven 2 site skin. In addition to using <tt>stylus-ext-skin</tt>
 * within your <tt>site.xml</tt>, you have to specify either the <tt>brush</tt>
 * or the <tt>brush-autodetect</tt> macro parameter (see
 * <a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter">SyntaxHighlighter</a>
 * for more information about the underlying syntax highlighter
 * configuration details).
 * 
 * @see BaseMacro
 * 
 * @author milan.skuhra
 * @author vojtech.szocs
 * 
 * @plexus.component role="org.apache.maven.doxia.macro.Macro" role-hint="code-snippet"
 */
public class CodeSnippetMacro extends BaseMacro {

    /**
     * @see org.apache.maven.doxia.macro.Macro#execute(org.apache.maven.doxia.sink.Sink, org.apache.maven.doxia.macro.MacroRequest)
     */
    public void execute(Sink sink, MacroRequest request) throws MacroExecutionException {
        String id = getParameterValue(request, "id", false);
        String encoding = getParameterValue(request, "encoding", false);
        String brush = getParameterValue(request, "brush", false);
        Object brushAutodetect = getParameterValue(request, "brush-autodetect", false);
        String shParams = getParameterValue(request, "sh-params", false);
        
        if (encoding == null)
            encoding = DEFAULT_ENCODING;
        
        URL url = getResourceUrl(request, "url", "file");
        
        if (brushAutodetect != null) {
            String urlString = url.toString();
            brush = urlString.substring(urlString.lastIndexOf('.') + 1);
        }
        
        CodeSnippet snippet;
        
        try {
            snippet = new CodeSnippet(id, url, encoding);
        } catch (IOException e) {
            throw new MacroExecutionException("Error while processing code snippet with source URL " + url, e); 
        }
        
        if (brush != null) {
            StringBuilder params = new StringBuilder();
            params.append("brush: ").append(brush);
            
            if (shParams != null) {
                params.append("; ").append(shParams);
            }
            
            snippet.setAttribute("class", params.toString());
        }
        
        sink.rawText(snippet.toString());
    }
    
}
